ListController = Class.create(Controller, {     
    prepareHTML: function() {
        if (this.clicker) delete this.clicker;
        this.clicker = new Clicker(this.params.name, this.selectItem.bind(this));

        if (this.sub_clicker) delete this.clicker;
            this.sub_clicker = new Clicker('add_'+this.params.name, this.addSubItem.bind(this));

		if (this.selectedId)
		    $(this.params.name+'_'+this.selectedId).addClassName('selected');
		
		//expanding tree functionality
		new Clicker('exp', this.expand.bind(this)); 

		if(this.params.view_type == 'ordered_tree') this.orderedPrepare();
        if (this.params.view_type != 'flat') {
			//Навешиваем штуки на листья!!! Да, Ваня стал истеричен и пишет везде по куче восклицательных знаков			
			new Clicker('lleaf', this.getLeaves.bind(this));
		}
    },
    
	orderedPrepare: function() {
		j$('[id ^= "sortable_"]').each(function() { 
            //V: Не нравится мне это замыкание. Можно как-то избежать?
            var sortEl = j$(this);
            var parent_id = this.id.substring('sortable_'.length);
            
            var that = this;
        
            Sortable.create(this.id, {
                tag:'div', 
                handle:'dr', 
                constraint:'vertical', 
                onUpdate: function(obj, event) {
                    ids = Sortable.sequence(that.id).join(',');
        
                    request('objects/save_order', {'ids':ids, 'parent_id': parent_id, class_name:getParam('class_name')});
                }
            });
        });
	},
	
	getLeaves: function(id) {
		if (!this.defer(this.getLeaves.bind(this), id)) return;
		this.params.onLeavesLoad(id);
	},
	
	unselect: function() {
		if (this.selectedId)
		    $(this.params.name+'_'+this.selectedId).removeClassName('selected');
		this.selectedId = false;
		return this;
	},
	
	unselectLeaf: function() {
		if (this.selectedLeafId)
            $('lleaf'+'_'+this.selectedLeafId).removeClassName('selected-leaf');
        this.selectedLeafId = false;
	},
	
	selectLeaf: function(id) {
        this.selectItem(id, true);
        if (this.selectedLeafId)
            $('lleaf'+'_'+this.selectedLeafId).removeClassName('selected-leaf');

        this.selectedLeafId = id;
        $('lleaf'+'_'+this.selectedLeafId).addClassName('selected-leaf');
	},
	
    selectItem: function(id, prevent) {
        if (!this.defer(this.selectItem.bind(this), id, prevent)) return;

		this.unselectLeaf();
		
		var need_action;
		if (prevent)
            need_action = false;
		else
		    need_action = true;

        if (this.selectedId || this.selectedId === 0) {
            $(this.params.name+'_'+this.selectedId).removeClassName('selected');
            if (this.selectedId == id)
                need_action = false;         
        }
        
        this.selectedId = id;

        $(this.params.name+'_'+this.selectedId).addClassName('selected');
        
        //if already clicked on "+" somewhere, then hide "Новый" element
        if(this.newItem) {
            $(this.newItem).hide(); //TODO: add jQuery.hide(200) functionality
            $(this.newItem).remove();
            this.newItem = undefined;
        }
        
        if (need_action) {
            this.params.action(this.selectedId);
        }                       
    },
	
	addSubItem: function(id) {
        if (!this.defer(this.selectItem.bind(this), id)) return;
        
        //if adding to node with hidden children, then expand it
        show($('sortable_'+id));
        j$('#exp_'+id).removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-se');
        
        //remove previous selection
        if(this.selectedId)
            $(this.params.name+'_'+this.selectedId).removeClassName('selected');
        
        //if already clicked "+" somewhere else
        if(this.newItem) {
            $(this.newItem).hide(); //TODO: add jQuery.hide(200) functionality
            $(this.newItem).remove();
            this.newItem = undefined;
        }
        
        //16 is the size of icons, we have 2 icons, so resulting offset is 16*2 
        $('sortable_'+id).insert(
                {top:'<div style="padding-left:'+ (16*2 + 1*getParams()['tree_padding']) +'px"> <a id="new_'+this.params.name+'" class="action selected">Новый</a></div>'}
        );
        
        //remember new item 
        this.newItem = document.getElementById('new_'+this.params.name);
        
        //calling update object controller with new form from sender 
        this.params.setFormParams({'parent_id': id});
        this.params.action(0);
    },
    
    expand: function(id) {
        j$('#sortable_'+id).toggle();
        j$('#exp_'+id).toggleClass('ui-icon-triangle-1-e').toggleClass('ui-icon-triangle-1-se');
    }
});
	
ObjectController = Class.create(Controller, {     
    prepareHTML: function() {
		for (editor in CKEDITOR.instances) CKEDITOR.remove(CKEDITOR.instances[editor]);
		if (this.form) delete this.form;
		this.form = new FormSender('fs', 'objects/edit');
		this.form.addListener(this.onFormSend.bind(this));
		this.form.addFormParams(this.additional_params);
		
		//Обработчик даты
		j$('.datepicker').datepicker();
		
		//Обработчик кнопки удалить 
        if ($('fs_delete')) $('fs_delete').onclick = Page.onDelete;
		
		//Обработчки на удаление файлов
		//if (this.clicker) delete this.clicker;
        new Clicker('delete-file', this.deleteFile.bind(this));
		new Clicker('add-file', this.addFile.bind(this));

    },
	
	addFile: function(id) {
		var tmpl = $('template_'+id).innerHTML;
		$('add-file_'+id).insert({'before':tmpl});
	},
	
	deleteFile: function(id) {
		request('objects/delete_file', {'field':id, 'id':getValue('fs_id'), 'class_name':getParam('class_name')}, update(this))
	},
	
	onFormSend: function(params) {
		this.params.action();
        if (params.get('file_sends')) this.update();
		if (params.get('id')) this.params.onNew(params.get('id'));
	},
	
	setFormParams: function (params) {
	    this.additional_params = params;
	}
});